<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box {
                width: 200px;
                height: 200px;
                background-color: red;
            }

            .default-img {
                width: 300px;
            }

            img {
                height: 150px;
            }

            .box1 {
                height: 20vw;
                background-color: aquamarine;
            }
        </style>
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
        <link
            rel="stylesheet"
            href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/default.min.css"
        />
        <link rel="stylesheet" href="http://47.108.195.190:5000/mavon-editor/css/index.css" />
        <script src="//image.zlketang.com/public/news/others/blog/js/vue.min.js"></script>
        <script src="https://image.zlketang.com/public/news/others/js/element-ui.js"></script>
        <script src="//image.zlketang.com/public/news/others/js/localforage.min.js"></script>
        <script src="http://47.108.195.190:5000/netdist/highlight-1729689163838~1~.js"></script>
        <script src="http://47.108.195.190:5000/mavon-editor/mavon-editor.js"></script>
        <script src="./流程图/king_ui.js"></script>
    </head>

    <body>
        <div id="app" >
            1
            <mavon-editor
                v-if="isShow"
                ref="md"
                class="bug-c-movon-editor"
                v-model="value"
                :ishljs="true"
                :toolbars="toolbarsComPuted"
            ></mavon-editor>
            2
            <br />
            <img :src="img1" alt="" />
            {{aaaa}}
            <div class="box1" ref="box"></div>

            <pre>
            <code ref="myElement">
                // blob转file
                blobToFile(theBlob, fileName) {
                  theBlob.lastModifiedDate = new Date();
                  theBlob.name = fileName;
                  return theBlob;
                },
                // base64转blob
                dataURLtoBlob(dataurl) {
                  let arr = dataurl.split(','),
                    mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]),
                    n = bstr.length,
                    u8arr = new Uint8Array(n);
                  while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                  }
                  return new Blob([u8arr], { type: mime });
                },
                async uploadfun() {
                  let { base64Url } = await native?.getPicture({
                    quality: 100,
                    destinationType: 0,
                    allowEdit: false,
                    encodingType: 0,
                    saveToPhotoAlbum: false,
                    sourceType: 1,
                    mediaType: 0,
                    correctOrientation: true,
                    cameraDirection: 0
                  });
                  if (!base64Url) {
                    Toast('获取文件失败，请重试');
                    return;
                  }
                  let blob = await this.dataURLtoBlob(base64Url, 1);
                  let blobFile = await this.blobToFile(blob, new Date().getTime() + '.jpg');
                  this.afterRead(blobFile);
                },
                async afterRead(file) {
                  // 上传到oss
                  let { url } = await upload(file).catch((e) => {
                    return {};
                  });
            
                  if (!url) {
                    Toast('上传失败,请重新上传!!!');
                    // 清空图片
                    this.$emit('input', []);
                    return;
                  }
            
                  this.$emit('input', [
                    {
                      url,
                      isImage: true
                    }
                  ]);
                },
                beforeDelete() {
                  this.$emit('input', []);
                }
            
            </code>
        </pre>
        </div>
    </body>

    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    isShow: false,
                    toolbars: {},
                    value: '',
                    img1: '',
                    img2: '',
                    img3: '',
                    img4: '',
                    aaa: '',
                    indexDBJS: null,
                    indexDBIMJ: null,
                    loadList: [
                        // {
                        //     css:'http://47.108.195.190:5000/mavon-editor/css/index.css'
                        // },
                        {
                            js: 'https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js',
                        },
                        {
                            js: 'https://cdn.bootcdn.net/ajax/libs/gsap/3.12.2/gsap.min.js',
                        },
                        {
                            js: 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/ScrollTrigger.min.js',
                        },
                        // {
                        //     js:'http://47.108.195.190:5000/mavon-editor/mavon-editor.js'
                        // }
                    ],
                    imgUrl: '',
                }
            },
            computed: {
                aaaa() {
                    // console.log('this.$refs?.box', this.$refs?.box)

                    return this.$refs?.box?.clientHeight || 0
                },

                // 富文本工具栏
                toolbarsComPuted() {
                    return Object.assign(
                        {
                            bold: true, // 粗体
                            italic: true, // 斜体
                            header: true, // 标题
                            underline: true, // 下划线
                            strikethrough: true, // 中划线
                            mark: true, // 标记
                            superscript: true, // 上角标
                            subscript: true, // 下角标
                            quote: true, // 引用
                            ol: true, // 有序列表
                            ul: true, // 无序列表
                            link: true, // 链接
                            imagelink: true, // 图片链接
                            code: true, // code
                            table: true, // 表格
                            fullscreen: true, // 全屏编辑
                            readmodel: true, // 沉浸式阅读
                            htmlcode: true, // 展示html源码
                            help: true, // 帮助
                            /* 1.3.5 */
                            undo: true, // 上一步
                            redo: true, // 下一步
                            trash: true, // 清空
                            save: true, // 保存（触发events中的save事件）
                            /* 1.4.2 */
                            navigation: true, // 导航目录
                            /* 2.1.8 */
                            alignleft: true, // 左对齐
                            aligncenter: true, // 居中
                            alignright: true, // 右对齐
                            /* 2.2.1 */
                            subfield: true, // 单双栏模式
                            preview: true, // 预览
                        },
                        this.toolbars,
                    )
                },
            },
            created() {
                // 连接js表
                this.indexDBJS = localforage.createInstance({
                    // 数据库名
                    name: 'kl-db',
                    // 表名
                    storeName: 'js-table',
                })

                // 连接图片资源表
                this.indexDBIMJ = localforage.createInstance({
                    // 数据库名
                    name: 'kl-db',
                    // 表名
                    storeName: 'img-table',
                })

                this.init()

                let imgs = {
                    img1: 'https://pic3.zhimg.com/80/v2-d8e1c695f6f11a6ba6e1d9c465a541c6_1440w.webp',
                }
                this.getindexDBIMJ(imgs, this.indexDBIMJ)
            },
            mounted() {
                this.observeWidth()
            },
            methods: {
                observeWidth() {
                    const element = this.$refs.myElement
                    this.resizeObserver = new ResizeObserver((entries) => {
                        for (let entry of entries) {
                            console.log('Element width:', entry.contentRect.width)
                            // 在这里处理宽度变化的逻辑
                        }
                    })

                    this.resizeObserver.observe(element)
                },
                // 页面业务入口
                begin() {
                    // console.log(window['king-ui-pro'])

                    hljs.highlightAll()
                    Vue.component('mavon-editor', MavonEditor.mavonEditor)
                    this.isShow = true
                },
                // 初始化
                async init() {
                    let { loadList } = this
                    this.loadToIndexDB(loadList, this.indexDBJS)
                        .then((res) => {
                            this.begin()
                        })
                        .catch((err) => {})
                },
                // 从indexDB中获取图片
                async getindexDBIMJ(imgs, localforage) {
                    // 将blob对象转换为base64
                    function blobToBase64(blobFile) {
                        return new Promise((resolve, reject) => {
                            const reader = new FileReader()
                            reader.readAsDataURL(blobFile)
                            reader.onload = (e) => {
                                const res = e.target.result
                                resolve(res)
                            }

                            reader.onerror = (e) => {
                                reject(e)
                            }
                        })
                    }

                    let imgsArr = Object.keys(imgs)
                    imgsArr.forEach(async (item) => {
                        const url = imgs[item]
                        let res = await localforage.getItem(url)
                        if (res) {
                            this[item] = res
                            return
                        }
                        this[item] = url
                        fetch(url)
                            .then((response) => response.blob())
                            .then(async (res) => {
                                try {
                                    let file = await blobToBase64(res)
                                    localforage.setItem(url, file)
                                } catch (e) {}
                            })
                    })
                },

                /**
                 * 封装一个动态加载js，并会将请求回来的文件保存到indexDB中的方法
                 * arr 需要动态加载的文件数组 示例 [{js:'aaa.js',isAppendHead:true},{css:'aaa.css'}]
                 */
                loadToIndexDB(arr, localforage) {
                    // 将blob对象转换为base64
                    function blobToBase64(blobFile) {
                        return new Promise((resolve, reject) => {
                            const reader = new FileReader()
                            reader.readAsDataURL(blobFile)
                            reader.onload = (e) => {
                                const res = e.target.result
                                resolve(res)
                            }

                            reader.onerror = (e) => {
                                reject(e)
                            }
                        })
                    }

                    // 将文件注入到页面 type: js/css
                    function loadScript(url, row) {
                        let { isAppendHead = false, js, css } = row
                        let type = css ? 'css' : 'js'
                        if (!url) {
                            return Promise.reject('failed')
                        }
                        // 防止重复加载
                        if (
                            (type === 'js' && document.querySelector(`script[src="url"]`)) ||
                            (type === 'css' && document.querySelector(`link[href="url"]`))
                        ) {
                            return Promise.resolve('successful')
                        }

                        return new Promise((resolve, reject) => {
                            let scriptDom = ''
                            if (type === 'js') {
                                scriptDom = document.createElement('script')
                                scriptDom.setAttribute('src', url)
                                scriptDom.setAttribute('type', 'text/javascript')
                            }

                            if (type === 'css') {
                                scriptDom = document.createElement('link')
                                scriptDom.setAttribute('href', url)
                                scriptDom.setAttribute('rel', 'stylesheet')
                            }
                            document[isAppendHead ? 'head' : 'body'].appendChild(scriptDom)
                            scriptDom.onload = () => {
                                resolve('successful')
                            }
                            scriptDom.onerror = () => {
                                // console.log('加载失败', row)
                                resolve('failed')
                            }
                        })
                    }
                    let arr1 = []
                    arr.forEach((element) => {
                        let url = element.js ? element.js : element.css
                        arr1.push(
                            localforage
                                .getItem(url)
                                .then(async (res) => {
                                    if (res) {
                                        await loadScript(res, element)
                                        return res
                                    }
                                    await loadScript(url, element)
                                    fetch(url)
                                        .then((response) => response.blob())
                                        .then(async (res) => {
                                            try {
                                                let file = await blobToBase64(res)
                                                // 保存
                                                localforage.setItem(url, file)
                                            } catch (err) {
                                                return false
                                            }
                                        })
                                        .catch((err) => {
                                            return false
                                        })
                                })
                                .catch((err) => {
                                    // console.log('getData-err', err)
                                }),
                        )
                    })
                    return Promise.all(arr1)
                },
            },
        })
    </script>
</html>
